<?php

namespace shisou\tpgii\lib;

use think\db\BaseQuery;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

/**
 * @mixin BaseQuery
 * @method BaseQuery where($field, $op = null, $condition = null) static where
 * @method self find($data = null)
 */
class AR extends \think\model
{

    const STATUS = [
        '0'  => '无效',
        '1'  => '正常',
        '9'  => '待审',
        '-1' => '删除',
    ];

    /**
     * 新增前
     * @param \think\Model $data
     *
     * @return false
     */
    public static function onBeforeInsert($data)
    {
        $data->created_at = $data->created_at ?? date('Y-m-d H:i:s');
        $data->updated_at = $data->updated_at ?? '0000-00-00 00:00:00';
        $data->status     = $data->status ?? 1;

        foreach ($data->schema as $key => $value) {
            // 过滤 primary key auto_increment 字段
            if ($key == 'id') {
                continue;
            }

            if (is_null($data->$key)) {
                try {
                    switch ($value) {
                        case 'char':
                        case 'varchar':
                        case 'text':
                            $data->$key = '';
                            break;
                        case 'tinyint':
                        case 'int':
                        case 'decimal':
                            $data->$key = 0;
                            break;
                        case 'datetime':
                            $data->$key = '0000-00-00 00:00:00';
                            break;
                        case 'date':
                            $data->$key = '0000-00-00';
                            break;
                        default:
                            break;
                    }
                } catch (\Throwable  $e) {
                    return false;
                }
            }
        }
    }

    /**
     * 修改前
     * @param \think\Model $data
     *
     * @return mixed|void
     */
    public static function onBeforeUpdate($data)
    {
        $data->updated_at = date('Y-m-d H:i:s');
    }

    /**
     * @param null $data
     *
     * @return static
     */
    public static function findOrNew($data = null): self
    {
        return parent::findOrEmpty($data);
    }

    public static function findOne($data = null)
    {
        if (is_numeric($data)) {
            $data = ['id' => $data];
        }

        try {
            return self::where($data)
                ->find();
        } catch (DataNotFoundException | ModelNotFoundException | DbException $e) {
            return null;
        }
    }

    /**
     * 处理条件查询
     * @param array $filterCond
     */
    public static function filterWhere($filterCond)
    {
        $rawCond = [];

        foreach ($filterCond as $k => $v) {
            if (is_array($v)) {
                if (empty($v) || $v[2] === '' || $v[2] === null || $v[2] === 'null' || $v[2] === 'undefined') {
                    unset($filterCond[$k]);
                } elseif (is_null(str_replace('%', '', $v[2])) || str_replace('%', '', $v[2]) === '') {
                    unset($filterCond[$k]);
                }
            } else {
                if (is_null(str_replace('%', '', $v)) || str_replace('%', '', $v) === '') {
                    unset($filterCond[$k]);
                } elseif (!is_array(str_replace('%', '', $v)) && (!is_null(str_replace('%', '', $v)) && str_replace('%', '', $v) != '')) {
                    $rawCond[$k] = $v;
                    unset($filterCond[$k]);
                }
            }
        }

        return self::where(array_values($filterCond))
            ->where($rawCond);
    }

    /**
     * 查询列表, 可带分页
     * @param array|null $where       查询条件
     * @param array|null $pageLimit   [页数,条数]
     * @param array|null $with        关联表
     * @param array|null $orderFields [查询排序,查询字段]
     * @param array|null $hasWheres   关联条件查询
     * @return array|AR[]
     */
    public function findList(
        array $where = null,
        array $pageLimit = null,
        array $with = null,
        array $orderFields = null,
        array $hasWheres = null
    )
    {
        $fields = is_null($orderFields) ? $this->table . '.*' : $orderFields[1];
        $order  = is_null($orderFields) ? [$this->table . '.id' => SORT_DESC] : $orderFields[0];
        $where  = is_null($where) ? ['status' => 1] : $where;

        $schema = array_keys($this->schema);
        foreach ($where as $k => $v) {
            if (is_array($v) && in_array($v[0], $schema)) {
                $where[$k][0] = $this->table . '.' . $v[0];
            }
            if (!is_array($v) && in_array($k, $schema)) {
                $where[$k] = $this->table . '.' . $k;
            }
        }

        $total = $this->filterWhere($where);
        $list  = $this->filterWhere($where);

        if (!is_null($with)) {
            $list = $list->with($with);
        }

        foreach ($hasWheres as $k => $v) {
            $total = $total->hasWhere($k, $v);
            $list  = $list->hasWhere($k, $v);
        }

        if (!is_null($pageLimit) && $pageLimit[0] > 0) {
            $list = $list->page($pageLimit[0], $pageLimit[1] ?? 10);
        }
        if (!is_null($pageLimit) && $pageLimit[0] == 0 && $pageLimit[1] > 0) {
            $list = $list->limit($pageLimit[1]);
        }

        $total = $total->count();

        $list = $list->field($fields)
            ->order($order)
            ->select();

        return [
            'total' => $total,
            'rows'  => $list,
        ];
    }

    // ---------- Custom code below ----------
}
